package com.cardcaptorsakura.model.entity;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.CompoundIndexes;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 记忆实体类
 * 存储用户交互记忆、偏好设置、历史对话等信息
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "memories")
@CompoundIndexes({
    @CompoundIndex(name = "user_type_idx", def = "{'userId': 1, 'memoryType': 1}"),
    @CompoundIndex(name = "user_time_idx", def = "{'userId': 1, 'createdAt': -1}"),
    @CompoundIndex(name = "persona_time_idx", def = "{'personaId': 1, 'createdAt': -1}"),
    @CompoundIndex(name = "vector_search_idx", def = "{'embedding': '2dsphere'}")
})
public class Memory {

    /**
     * 记忆ID
     */
    @Id
    private String id;

    /**
     * 用户ID
     */
    @Indexed
    private String userId;

    /**
     * 人格ID
     */
    @Indexed
    private String personaId;

    /**
     * 会话ID
     */
    @Indexed
    private String conversationId;

    /**
     * 记忆类型
     */
    @Indexed
    private MemoryType memoryType;

    /**
     * 记忆标题
     */
    private String title;

    /**
     * 记忆内容
     */
    private String content;

    /**
     * 原始文本（用于向量化）
     */
    private String rawText;

    /**
     * 向量嵌入
     */
    private List<Double> embedding;

    /**
     * 向量维度
     */
    private Integer embeddingDimension;

    /**
     * 重要性评分（0-100）
     */
    @Builder.Default
    private Integer importance = 50;

    /**
     * 情感标签
     */
    private List<String> emotionTags;

    /**
     * 主题标签
     */
    private List<String> topicTags;

    /**
     * 关键词
     */
    private List<String> keywords;

    /**
     * 实体信息
     */
    private Map<String, Object> entities;

    /**
     * 上下文信息
     */
    private ContextInfo context;

    /**
     * 访问次数
     */
    @Builder.Default
    private Integer accessCount = 0;

    /**
     * 最后访问时间
     */
    private LocalDateTime lastAccessedAt;

    /**
     * 创建时间
     */
    @Builder.Default
    private LocalDateTime createdAt = LocalDateTime.now();

    /**
     * 更新时间
     */
    @Builder.Default
    private LocalDateTime updatedAt = LocalDateTime.now();

    /**
     * 过期时间
     */
    private LocalDateTime expiresAt;

    /**
     * 是否已删除
     */
    @Builder.Default
    private Boolean deleted = false;

    /**
     * 删除时间
     */
    private LocalDateTime deletedAt;

    /**
     * 记忆来源
     */
    private MemorySource source;

    /**
     * 置信度（0-1）
     */
    @Builder.Default
    private Double confidence = 1.0;

    /**
     * 相关记忆ID列表
     */
    private List<String> relatedMemoryIds;

    /**
     * 父记忆ID
     */
    private String parentMemoryId;

    /**
     * 子记忆ID列表
     */
    private List<String> childMemoryIds;

    /**
     * 记忆链ID
     */
    private String memoryChainId;

    /**
     * 版本号
     */
    @Builder.Default
    private Integer version = 1;

    /**
     * 扩展属性
     */
    private Map<String, Object> metadata;

    /**
     * 记忆类型枚举
     */
    public enum MemoryType {
        CONVERSATION,       // 对话记忆
        USER_PREFERENCE,    // 用户偏好
        PERSONA_STATE,      // 人格状态
        INTERACTION,        // 交互记忆
        KNOWLEDGE,          // 知识记忆
        EMOTION,            // 情感记忆
        HABIT,              // 习惯记忆
        GOAL,               // 目标记忆
        FEEDBACK,           // 反馈记忆
        CONTEXT,            // 上下文记忆
        SYSTEM,             // 系统记忆
        CUSTOM              // 自定义记忆
    }

    /**
     * 记忆来源枚举
     */
    public enum MemorySource {
        USER_INPUT,         // 用户输入
        SYSTEM_GENERATED,   // 系统生成
        AI_INFERENCE,       // AI推理
        EXTERNAL_API,       // 外部API
        MANUAL_INPUT,       // 手动输入
        IMPORTED,           // 导入
        LEARNED             // 学习获得
    }

    /**
     * 上下文信息
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ContextInfo {
        /**
         * 时间上下文
         */
        private TimeContext timeContext;

        /**
         * 位置上下文
         */
        private LocationContext locationContext;

        /**
         * 设备上下文
         */
        private DeviceContext deviceContext;

        /**
         * 应用上下文
         */
        private ApplicationContext applicationContext;

        /**
         * 社交上下文
         */
        private SocialContext socialContext;

        /**
         * 环境上下文
         */
        private Map<String, Object> environmentContext;
    }

    /**
     * 时间上下文
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class TimeContext {
        /**
         * 时间戳
         */
        private LocalDateTime timestamp;

        /**
         * 时区
         */
        private String timezone;

        /**
         * 星期几
         */
        private String dayOfWeek;

        /**
         * 时间段（morning, afternoon, evening, night）
         */
        private String timeOfDay;

        /**
         * 季节
         */
        private String season;

        /**
         * 是否节假日
         */
        private Boolean isHoliday;

        /**
         * 节假日名称
         */
        private String holidayName;
    }

    /**
     * 位置上下文
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class LocationContext {
        /**
         * 国家
         */
        private String country;

        /**
         * 省份/州
         */
        private String province;

        /**
         * 城市
         */
        private String city;

        /**
         * 经度
         */
        private Double longitude;

        /**
         * 纬度
         */
        private Double latitude;

        /**
         * IP地址
         */
        private String ipAddress;

        /**
         * 位置类型（home, office, public, etc.）
         */
        private String locationType;
    }

    /**
     * 设备上下文
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class DeviceContext {
        /**
         * 设备类型（mobile, desktop, tablet, etc.）
         */
        private String deviceType;

        /**
         * 操作系统
         */
        private String operatingSystem;

        /**
         * 浏览器
         */
        private String browser;

        /**
         * 屏幕分辨率
         */
        private String screenResolution;

        /**
         * 用户代理
         */
        private String userAgent;

        /**
         * 设备ID
         */
        private String deviceId;

        /**
         * 网络类型（wifi, cellular, ethernet, etc.）
         */
        private String networkType;
    }

    /**
     * 应用上下文
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ApplicationContext {
        /**
         * 应用版本
         */
        private String appVersion;

        /**
         * 功能模块
         */
        private String module;

        /**
         * 页面/界面
         */
        private String page;

        /**
         * 操作类型
         */
        private String actionType;

        /**
         * 会话持续时间（秒）
         */
        private Long sessionDuration;

        /**
         * 交互次数
         */
        private Integer interactionCount;
    }

    /**
     * 社交上下文
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SocialContext {
        /**
         * 是否群聊
         */
        private Boolean isGroupChat;

        /**
         * 群组ID
         */
        private String groupId;

        /**
         * 参与者列表
         */
        private List<String> participants;

        /**
         * 社交关系
         */
        private String relationship;

        /**
         * 互动频率
         */
        private String interactionFrequency;

        /**
         * 亲密度评分（0-100）
         */
        private Integer intimacyScore;
    }

    /**
     * 增加访问次数
     */
    public void incrementAccessCount() {
        this.accessCount = (this.accessCount == null ? 0 : this.accessCount) + 1;
        this.lastAccessedAt = LocalDateTime.now();
        this.updatedAt = LocalDateTime.now();
    }

    /**
     * 更新重要性评分
     */
    public void updateImportance(int newImportance) {
        this.importance = Math.max(0, Math.min(100, newImportance));
        this.updatedAt = LocalDateTime.now();
    }

    /**
     * 添加情感标签
     */
    public void addEmotionTag(String tag) {
        if (this.emotionTags == null) {
            this.emotionTags = new java.util.ArrayList<>();
        }
        if (!this.emotionTags.contains(tag)) {
            this.emotionTags.add(tag);
            this.updatedAt = LocalDateTime.now();
        }
    }

    /**
     * 添加主题标签
     */
    public void addTopicTag(String tag) {
        if (this.topicTags == null) {
            this.topicTags = new java.util.ArrayList<>();
        }
        if (!this.topicTags.contains(tag)) {
            this.topicTags.add(tag);
            this.updatedAt = LocalDateTime.now();
        }
    }

    /**
     * 添加关键词
     */
    public void addKeyword(String keyword) {
        if (this.keywords == null) {
            this.keywords = new java.util.ArrayList<>();
        }
        if (!this.keywords.contains(keyword)) {
            this.keywords.add(keyword);
            this.updatedAt = LocalDateTime.now();
        }
    }

    /**
     * 添加相关记忆
     */
    public void addRelatedMemory(String memoryId) {
        if (this.relatedMemoryIds == null) {
            this.relatedMemoryIds = new java.util.ArrayList<>();
        }
        if (!this.relatedMemoryIds.contains(memoryId)) {
            this.relatedMemoryIds.add(memoryId);
            this.updatedAt = LocalDateTime.now();
        }
    }

    /**
     * 软删除
     */
    public void softDelete() {
        this.deleted = true;
        this.deletedAt = LocalDateTime.now();
        this.updatedAt = LocalDateTime.now();
    }

    /**
     * 恢复删除
     */
    public void restore() {
        this.deleted = false;
        this.deletedAt = null;
        this.updatedAt = LocalDateTime.now();
    }

    /**
     * 检查是否过期
     */
    public boolean isExpired() {
        return expiresAt != null && LocalDateTime.now().isAfter(expiresAt);
    }

    /**
     * 检查是否活跃（最近访问过）
     */
    public boolean isActive(int days) {
        if (lastAccessedAt == null) {
            return false;
        }
        return lastAccessedAt.isAfter(LocalDateTime.now().minusDays(days));
    }

    /**
     * 计算记忆年龄（天数）
     */
    public long getAgeInDays() {
        return java.time.temporal.ChronoUnit.DAYS.between(createdAt, LocalDateTime.now());
    }

    /**
     * 计算访问频率（次数/天）
     */
    public double getAccessFrequency() {
        long ageInDays = getAgeInDays();
        if (ageInDays == 0) {
            return accessCount;
        }
        return (double) accessCount / ageInDays;
    }

    /**
     * 获取记忆摘要
     */
    public String getSummary() {
        String contentSummary = content != null && content.length() > 100 ? 
                content.substring(0, 100) + "..." : content;
        return String.format("[%s] %s - %s", memoryType, title, contentSummary);
    }

    /**
     * 检查是否包含关键词
     */
    public boolean containsKeyword(String keyword) {
        if (keyword == null) return false;
        
        String lowerKeyword = keyword.toLowerCase();
        
        // 检查标题
        if (title != null && title.toLowerCase().contains(lowerKeyword)) {
            return true;
        }
        
        // 检查内容
        if (content != null && content.toLowerCase().contains(lowerKeyword)) {
            return true;
        }
        
        // 检查关键词列表
        if (keywords != null) {
            return keywords.stream().anyMatch(k -> k.toLowerCase().contains(lowerKeyword));
        }
        
        return false;
    }

    /**
     * 检查是否匹配标签
     */
    public boolean hasTag(String tag) {
        if (tag == null) return false;
        
        String lowerTag = tag.toLowerCase();
        
        // 检查情感标签
        if (emotionTags != null && emotionTags.stream().anyMatch(t -> t.toLowerCase().equals(lowerTag))) {
            return true;
        }
        
        // 检查主题标签
        if (topicTags != null && topicTags.stream().anyMatch(t -> t.toLowerCase().equals(lowerTag))) {
            return true;
        }
        
        return false;
    }

    /**
     * 更新向量嵌入
     */
    public void updateEmbedding(List<Double> newEmbedding) {
        this.embedding = newEmbedding;
        this.embeddingDimension = newEmbedding != null ? newEmbedding.size() : null;
        this.updatedAt = LocalDateTime.now();
    }

    /**
     * 计算与另一个记忆的相似度（基于向量）
     */
    public double calculateSimilarity(Memory other) {
        if (this.embedding == null || other.embedding == null) {
            return 0.0;
        }
        
        if (this.embedding.size() != other.embedding.size()) {
            return 0.0;
        }
        
        // 计算余弦相似度
        double dotProduct = 0.0;
        double normA = 0.0;
        double normB = 0.0;
        
        for (int i = 0; i < this.embedding.size(); i++) {
            double a = this.embedding.get(i);
            double b = other.embedding.get(i);
            
            dotProduct += a * b;
            normA += a * a;
            normB += b * b;
        }
        
        if (normA == 0.0 || normB == 0.0) {
            return 0.0;
        }
        
        return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
    }
}